package server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;

public class ConnectionEstablisher {
	public static void main(String args[]) {

		SSLServerSocket ss = null;
		try {
			ss = (SSLServerSocket) getServerSocketFactory().createServerSocket(
					4000);
		} catch (IOException e) {

			e.printStackTrace();
		}
		ss.setNeedClientAuth(true);
		SSLSocket socket = null;
		while (true) {
			try {
				socket = (SSLSocket) ss.accept();

				SSLSession session = socket.getSession();
				X509Certificate cert = (X509Certificate) session
						.getPeerCertificateChain()[0];
				String subject = cert.getSubjectDN().getName();
				System.out.println(subject);
				BufferedReader in = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				PrintWriter out = new PrintWriter(new BufferedWriter(
						new OutputStreamWriter(socket.getOutputStream())));

				PassVerifier pv = new PassVerifier(out, in);
				pv.sendChallenge();
				if (pv.waitNAct()) {
					out.println("Welcome" + " " + subject.substring(3));
					out.flush();
					new Parser(new Subjects().getSubject(subject.substring(3)),
							out, in);
				} else {
					out.println("You are not worthy enough...");
					out.flush();

				}
			} catch (IOException e) {

				e.printStackTrace();
			}
			try {
				socket.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

	}

	private static SSLServerSocketFactory getServerSocketFactory() {
		SSLServerSocketFactory ssf = null;
		try {
			// set up key manager to do server authentication
			SSLContext ctx;
			KeyManagerFactory kmf;
			TrustManagerFactory tmf;
			KeyStore ts;
			KeyStore ks;
			char[] passphrase = "password".toCharArray();

			ts = KeyStore.getInstance("JKS");
			ts.load(new FileInputStream("cert script/test/Server.jks"),
					passphrase);
			tmf = TrustManagerFactory.getInstance("SunX509");
			tmf.init(ts);

			ctx = SSLContext.getInstance("SSL");
			kmf = KeyManagerFactory.getInstance("SunX509");
			ks = KeyStore.getInstance("JKS");

			ks.load(new FileInputStream("cert script/test/Server.jks"),
					passphrase);
			kmf.init(ks, passphrase);
			System.out.println(((X509TrustManager) tmf.getTrustManagers()[0])
					.getAcceptedIssuers()[0].getSubjectDN().getName());
			ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
			ssf = ctx.getServerSocketFactory();
			return ssf;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
